/******************************************************************************************
* Function: add_to_list
* Description : Populate the DS on Tracker
* Date: Nov 14th '10
* Author: Aditya Kr Verma
********************************************************************************************/

//#include "tracker.h"

/******************************Functions definations**************************************/

/* This function just makes Initial 1st time (peer_count = 1), DS popuate for each file, 
*  remaining all updates for each part are handled by update function 
*/

void append_file_part(struct node **new1, char *fname, int seed_id,int part_number, int myport, char IP_addr[IPv4_SIZE])
{
    struct node *temp;
    struct file_part *new_temp, *r;
    char * f_name;
    int peer_count = 0;

    //seed_id = peer_id;

   

    temp = *new1 ;
	
    f_name = temp->value;
		//printf("\n Inside Append file part with file name: %s ",f_name);
		fflush(stdout);  
	while ( strcmp((char *)fname, (const char*)f_name)!= 0)
	{
		temp = temp->next;
		f_name = temp->value;
		if(temp->next == NULL && (strcmp((char *)fname, (const char*)f_name) != 0 ))
		{
			printf("\n Sorry ! File not present in the file_list. Needs to be added ");
			
			exit(1);
		}
	}
	printf("\n After Compare:%s ",temp->value);
		fflush(stdout);  
	peer_count = 1;	  
	if( temp->node_part == NULL)
	{       
               	new_temp = (struct file_part *)malloc ( sizeof ( struct file_part) ) ;

		new_temp-> next = NULL;                                                 
		new_temp-> part_num = part_number;

                new_temp-> seeder_list[peer_count].seeder_id = seed_id;
                new_temp-> seeder_list[peer_count].sd_sin.sin_port = htons(myport) ; // ????
		inet_pton(AF_INET,IP_addr,&(new_temp-> seeder_list[peer_count].sd_sin.sin_addr));
                new_temp-> seeder_list[peer_count].sd_sin.sin_family = AF_INET ;

                /*
  			Few more fields to put.. like dwld status n all .......
     		*/


		temp->node_part = new_temp;
		//printf("\n Inside append_file_part : %s , of part number %d , seeder_IP %s and Port ", temp->value, new_temp-> part_num,myport);
     	}

	else
	{
		new_temp = temp->node_part ;
		while ( new_temp -> next != NULL ) 
		new_temp = new_temp -> next ;

		r = (struct file_part *)malloc ( sizeof ( struct file_part ) ) ;
		r-> next = NULL;
		r-> part_num = part_number;
                r-> seeder_list[peer_count].seeder_id = seed_id;
                r-> seeder_list[peer_count].sd_sin.sin_port = htons(myport) ;
                inet_pton(AF_INET,IP_addr,&(r-> seeder_list[peer_count].sd_sin.sin_addr));
                r-> seeder_list[peer_count].sd_sin.sin_family = AF_INET ;	

                 /*
  			Few more fields to put.. like dwld status n all .......
     		*/

		inet_ntop(AF_INET,&(r-> seeder_list[peer_count].sd_sin.sin_addr),IP_addr,IPv4_SIZE); // presentation					 		                           
		new_temp-> next = r;
		printf("\n Inside append_file_part : \t%s, \t%d , \t%s, \t%d", temp->value, r-> part_num, IP_addr, ntohs(r-> seeder_list[peer_count].sd_sin.sin_port));

	}
}

/****************** append function *************************************************/


void append_list ( struct node ** new2, char * name )
{
struct node *temp, *r ;
   static int i=1;
	if ( *new2 == NULL )  // if the list is empty, create first node
    {
		printf("There is no file present , at start");
		fflush(stdout);
        temp = (struct node *)malloc ( sizeof ( struct node) ) ;
	    temp -> value = name ;
        temp -> next = NULL ;
        temp -> node_part = NULL;
        *new2 = temp ;
		printf("\n Inside append_list ( 1st Node ): %s ", temp->value);
		fflush(stdout);
		i++;
    }
    else
    {   		  
	temp = *new2 ;

	while ( temp  != NULL ) // go to last node 
	{	
		temp = temp -> next ;
		printf("Incrementing node in appendix list %d",i);
       fflush(stdout);
		i++;				
	}
	//printf("\n Appending ith %d at next location current location : %s ", i,temp->value);
	fflush(stdout);
	r = (struct node *)malloc ( sizeof ( struct node ) ) ; // add node at the end 
	r -> value = name ;
	r -> next = NULL ;
	r -> node_part = NULL;
	temp = r ;
	printf("\n Inside append_list : %s ", r->value);
	fflush(stdout);
	

    } 
}

/********************* Update function **************************/

void Update ( struct node **new1, char *fname, char * protocol, int p_id, int part_number, int myport, char IP_addr[IPv4_SIZE]) // 7 parameters
{
    struct node *temp;
    struct file_part *new_temp, *r;
    char * f_name, protocol_code;
    int i= 0;

    int peer_count ;  
    temp = *new1 ;

    protocol_code = protocol;
	
	
    f_name = temp->value;
		  
	while ( strcmp((char *)fname, (const char*)f_name)!= 0)
	{
		temp = temp->next;
		f_name = temp->value;
		if(temp->next == NULL && (strcmp((char *)fname, (const char*)f_name) != 0 ))
		{
			printf("\n Sorry ! File not present in the file_list. Needs to be added ");
			exit(1);
		}
	}

        new_temp = temp->node_part ;

	for ( i = 1 ; i < part_number ; i++ )
	new_temp = new_temp -> next ;

	if ( new_temp == NULL )
	{
		printf ( "\nThere are less than %d elements in list", part_number ) ;
		return ;
	}
    
	if ( new_temp->part_num == part_number)
	{        
            
		
             if ( protocol_code == 0x01) // seeder update
	     {
                for (peer_count=0;peer_count< MAX_PEERS;peer_count++) // Reach 
                {
		  if(new_temp->seeder_list[peer_count].seeder_id == NULL) ; // Initialise somewhere , this array as null. = {0};
                  break ; 
	        }
		new_temp-> seeder_list[peer_count].seeder_id = p_id;
		new_temp-> seeder_list[peer_count].sd_sin.sin_port = htons(myport) ; 
                //new_temp-> seeder_list[peer_count].sd_sin.sin_addr.s_addr = IP_addr ;
                inet_pton(AF_INET,IP_addr,&(new_temp-> seeder_list[peer_count].sd_sin.sin_addr));
                new_temp-> seeder_list[peer_count].sd_sin.sin_family = AF_INET ;
	     }

             else  // leecher update
	     {
                 for (peer_count=0;peer_count< MAX_PEERS;peer_count++) // Reach 
                 {
		   if(new_temp->leecher_list[peer_count].leecher_id == NULL ); // Initialise somewhere , this array as null. = {0};
                   break ; 
	         }
                 new_temp-> leecher_list[peer_count].leecher_id = p_id;
		 new_temp-> leecher_list[peer_count].lc_sin.sin_port = htons(myport) ; // ???? or just myport;
                 //new_temp-> leecher_list[peer_count].lc_sin.sin_addr.s_addr = IP_addr ;
                 inet_pton(AF_INET,IP_addr,&(new_temp-> leecher_list[peer_count].lc_sin.sin_addr));
                 new_temp-> leecher_list[peer_count].lc_sin.sin_family = AF_INET ;
	     }
          

		// new_temp->percent_downloaded = 99.900000; //               ???? reqd ?? when n w.r.t to whom ?? think ..
		//new_temp->seeder_list[1].seeder_id = peer_id;
                     
		
	}

       //printf("\n\n Percentage downloaded for part number %d is %f ",part_number, new_temp->percent_downloaded);
       printf("\n\n Its peer id is : %d \n\n ",new_temp->seeder_list[1].seeder_id);

}

void print_list(struct node *head)
{
	struct node * temp=head;
    struct file_part * horizontal;
	int i=0;
	char pipbuff[IPv4_SIZE]={0};

	if (temp != NULL)
    { 
    	//temp->value;
    	//printf("\n Head value %s",temp->value);
	while(temp!=NULL)
	{
		printf("\n ***********Head value %s********************",temp->value);
		fflush(stdout);
		if(temp->node_part==NULL)
			printf("\n The horizontal node is NULL");
  /*      if ( temp->node_part != NULL)
		{
        	horizontal = temp->node_part;
	  		while ( horizontal != NULL)
        	{ 
 
		        printf("\n***The Data in part list of file is:***");
    	        printf("\nPart number: %d",horizontal->part_num);
       
    		    printf("\n Seeder Info:\n");
    		    for(i=0;i<MAX_SEEDS;i++)
        		{
            		//************************************* Change the formatting specifiers according to length
            		printf("\tID:%5d", horizontal->seeder_list[i].seeder_id);
            		inet_ntop(AF_INET, &(horizontal->seeder_list[i].sd_sin.sin_addr), pipbuff, IPv4_SIZE);
            		printf("  Seeder ip is :%16s",pipbuff);    
            		memset(&pipbuff,0,IPv4_SIZE);
            		printf(" | ");
            		if((i%3)==2)
					{
            			printf("\n");
            		}
        		}
        		printf("\n Leecher Info:\n");
		        for(i=0;i<MAX_LEECHES;i++)
    		    {
        		    printf("\tID:%5d", horizontal->leecher_list[i].leecher_id);
            		inet_ntop(AF_INET, &(horizontal->leecher_list[i].lc_sin.sin_addr), pipbuff, IPv4_SIZE);
            		printf("  Leecher ip is :%16s",pipbuff);    
            		memset(&pipbuff,0,IPv4_SIZE);
           			printf(" | ");
            		if((i%3)==2)
					{
            			printf("\n");
           		 	}
        		}
        
        		horizontal=horizontal->next; // go to next horizontal node (FILE pART)
        		printf("************\n");
    		} //end of while
    
	     }
	*/
		temp=temp->next;
		printf("*********************************************************************************************\n");
		fflush(stdout);		
		}//end of while vertical
	}
}


/************************************ Read_DS_and_send *******************************/

char* Read_DS ( struct node **new1, int seq_no,char *fname, int part_number )
{
    struct node *temp;
    struct file_part *new_temp, *r;
    char * f_name;
    int i= 0;
    char send_buffer[100];
    char token3[100];
    int peer_id, port_no;
    char IP_addr[IPv4_SIZE];
    char* reply_protocol = "0x04";

    int ack_no = seq_no +1;
    temp = *new1 ;
	
    printf("\n Inside Read DS .... \n"); fflush(stdout);
    f_name = temp->value;
    printf("\n f_value %s, temp->value %s \n", f_name, temp->value); fflush(stdout);
		  
	while ( strcmp((char *)fname, (const char*)f_name)!= 0)
	{
		temp = temp->next;
		f_name = temp->value;
                printf("\n inside while ....");
               
		if(temp->next == NULL && (strcmp((char *)fname, (const char*)f_name) != 0 ))
		{
			printf("\n Sorry ! File not present in the file_list. Needs to be added ");
			//getch();
			exit(1);
		}
          
	}

	printf("\n Inside Read DS f_name is matched temp->value = %s",temp->value); fflush(stdout);
        
        new_temp = temp->node_part ;
	for ( i = 1 ; i < part_number ; i++ )
	new_temp = new_temp -> next ;

	if ( new_temp == NULL )
	{
		printf ( "\nThere are less than %d elements in list", part_number ) ;
		return ;
	}
         
	if ( new_temp->part_num == part_number)  // Need to read always seeder info .. reqd for seeding.
	{   
	  printf("\n Peer_id read from DS is %d",new_temp->seeder_list[1].seeder_id);
	  peer_id = new_temp->seeder_list[1].seeder_id;
          port_no = ntohs(new_temp->seeder_list[1].sd_sin.sin_port);        // ????? ???????????????? ok ??
	  // IP_addr = new_temp->seeder_list[1].sd_sin.sin_addr.s_addr; //  ????????????????????   ok ??
          inet_ntop(AF_INET,&(new_temp->seeder_list[1].sd_sin.sin_addr),IP_addr,IPv4_SIZE); // presentation 
                     
	}
     
	//sprintf(send_buffer,"%s$%d$%s$%d$%d$%s",reply_protocol,ack_no,fname,peer_id,port_no,IP_addr); // is protocol code %s or %u or %d ?? also IP YES ??
                 
         sprintf(send_buffer,"%s$%d$%s$%d",reply_protocol,ack_no,fname,peer_id); // FILL MORE ....

         printf("\n\n send buffer is : %s\n", send_buffer);
         return send_buffer; 

}


/************************************************* main() ****************************/


/*
int main()
{

	int i,j=0;
	struct node *head = NULL;
	struct file_part *fhead = NULL;
	int seeder_id = 101;
        int sequence_no = 80;
        char * info;
        char * protocol = 0x08;        // just for testing in main
        char * IP = "10.130.168.10";   // just for testing in main

	char string[10];

        printf("\n Initialise the Seeder list to be zero ");

      
	//memset(fhead->seeder_list,0,MAX_SEEDS);
	//memset(fhead->leecher_list,0,MAX_LEECHES);

	//printf("\n Initialise the Seeder list to be zero ");
	//fflush(stdout);

	//for(i=0;i<MAX_SEEDS;i++)
	
         // printf("\n Seeder list Initialise : %s",fhead->seeder_list[i]);
	
	//fflush(stdout);
        //for(i=0;i<MAX_LEECHES;i++)
	
          //printf("\n Leecher list Initialise : %s",fhead->leecher_list[i]);
	
        //fflush(stdout);
       
		

   	append_list(&head,"MI2");
	append_list(&head,"MI3");
	append_list(&head,"MI4");
	append_list(&head,"MI5");
	append_list(&head,"MI6");

	printf(" \n 	MYPORT is ................ %d",MYPORT);
	printf("\n\n Enter the name of the torrent for download  ");
	scanf("%s",string);

	printf("\n Now doing append_file_part ..");

	for (i=1;i<=NO_OF_PARTS;i++)
	append_file_part(&head,string, seeder_id,i, MYPORT,IP);
	//getch();

	printf("\n\n Now calling Update function ............");
	printf("\n Updaing .... filename = %s,seeder_id = %d, MYPORT = %d", string,seeder_id,MYPORT);
	Update(&head, string,protocol, seeder_id ,3, MYPORT, IP);
	//getch();
	
	
	printf("\n Now calling Read_DS function ...............");
        printf("\n filename = %s, seq no = %d",string,sequence_no);
	info = Read_DS(&head,string,sequence_no,3);
        printf("\n Reply to Sparta torrent is %s\n\n",info);

}

*/

